<template>
  <!-- 图片上传组件 -->
  <view class="upload-wrapper">
    <view class="upload-box">
      <input v-if="imgList.length < 3" type="file" id="upload-ele" multiple="" name="imgFile[]" accept="image/*" @change="uploadFile(quality)">
      <view class="desc" @click="imgUpTip">
        <text class="left">商品图片</text>
        <text class="right">点击上传</text>
      </view>
    </view>
    <view class="img-list" v-if="imgList.length > 0">
      <view class="item" v-for="(item, index) in imgList" :key="index">
        <text class="img-box">
          <img :src="item" alt="">
          <i class="icon iconfont" @click.stop="deleteImg(index)">&#xe617;</i>
        </text>
      </view>
    </view>
  </view>
</template>
<script>
var app = getApp()
var _this
export default {
  name: 'imgUploader',
  data () {
    return {
      toast: ''
    }
  },
  props: {
    'quality': Number // 图片质量
  },
  data () {
    return {
      total: { isShow: false, text: '' },
      imgList: [],
      fileList: [],
      max: 3
    }
  },
  created () {
	_this = this
    this.fileList = app.globalData.imgFiles
    if (this.fileList[0] && this.fileList[0].size) {
      for (let i = 0; i < this.fileList.length; i++) {
        let url = this.getObjectURL(this.fileList[i])
        this.imgList.push(url)
      }
    } else {
      this.fileList = []
    }
    this.$emit('getImgFile', this.fileList)
  },
  methods: {
    imgUpTip () {
      if (this.imgList.length >= 3) {
        this.toast && this.toast.close()
        this.toast = this.$toast('最多只能上传3张图片！')
      }
    },
    // 删除图片
    deleteImg (index) {
      this.fileList.splice(index, 1)
      this.imgList.splice(index, 1)
      this.$emit('getImgFile', this.fileList)
    },
    uploadFile (quality) {
      if (this.fileList.length == 3) {
        this.$toast('最多只能上传3张图片！')
        return
      }
      // files是input设置为file后的一个内置对象。files对象是一个只读属性，不可被修改。
      var oFile = document.getElementById('upload-ele').files[0]
      console.log('File Object', oFile)
      let imgurl = this.getObjectURL(oFile)
      this.imgList.push(imgurl)
      // 大小判断 如果大于1M就新型压缩处理
      // console.log('File Size Unit：KB',(oFile.size / 1024))
      if ((oFile.size / 1024) > 1024) {
        this.imgCompress(oFile, { quality: quality }, (base64Codes) => {
          let bl = this.convertBase64UrlToBlob(base64Codes)
          bl = this.convertBlobToFile(bl)
          this.fileList.push(bl)
          this.$emit('getImgFile', this.fileList)
        })
      } else {
        // 小与1M
        this.fileList.push(oFile)
        this.$emit('getImgFile', this.fileList)
        console.log('88888888fileList = ', this.fileList)
      }
    },
    // 将本地图片转化为可显示的
    getObjectURL (file) {
      let url = null
      if (window.createObjectURL != undefined) { // basic
        url = window.createObjectURL(file)
      } else if (window.URL != undefined) { // mozilla(firefox)
        url = window.URL.createObjectURL(file)
      } else if (window.webkitURL != undefined) { // webkit or chrome
        url = window.webkitURL.createObjectURL(file)
      }
      return url
    },
    /**
     * @description 图片压缩
     * @param {Object} file 压缩的文件
     * @param {Number} width 压缩后端宽度，宽度越小，字节越小
     */
    imgCompress (file, width, callBack) {
      var reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = (e) => {
        this.canvasDataURL(e.target.result, width, callBack)
      }
    },
    /**
     * 将以base64的图片url数据转换为Blob
     * @param urlData
     * 用url方式表示的base64图片数据
     */
    convertBase64UrlToBlob (urlData) {
      let arr = urlData.split(',')
      let mime = arr[0].match(/:(.*?);/)[1]
      let bstr = atob(arr[1])
      let n = bstr.length
      let u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new Blob([u8arr], { type: mime })
      // return new File([u8arr], 'file_' + Date.parse(new Date()) + '.jpg', { type: mime })
    },

    convertBlobToFile (theBlob) {
      theBlob.lastModifiedDate = new Date()
      theBlob.name = 'file_' + Date.parse(new Date()) + '.jpg'
      return theBlob
    },

    /**
     * @description 大于1M的图片进行重新绘制压缩
     */
    canvasDataURL (path, obj, callback) {
      var img = new Image()
      img.src = path
      img.onload = () => {
        let canvas = document.createElement('canvas')
        let ctx = canvas.getContext('2d')
        // 瓦片
        let tCanvas = document.createElement('canvas')
        let tctx = tCanvas.getContext('2d')
        let width = img.width
        let height = img.height
        // 如果图片大于四百万像素，计算压缩比并将大小压至400万以下
        let ratio
        if ((ratio = (width * height) / 4000000) > 1) {
          ratio = Math.sqrt(ratio)
          width /= ratio
          height /= ratio
        } else {
          ratio = 1
        }
        canvas.width = width
        canvas.height = height
        // 铺底色
        ctx.fillStyle = '#ffffff'
        ctx.fillRect(0, 0, canvas.width, canvas.height)
        // 如果图片像素大于100万则使用瓦片绘制
        let count
        if ((count = (width * height) / 1000000) > 1) {
          count = ~~(Math.sqrt(count) + 1) // 计算要分成多少瓦片，~~在这里表示取整
          // 计算每块瓦片的宽高
          let nw = ~~(width / count)
          let nh = ~~(height / count)
          tCanvas.width = nw
          tCanvas.height = nh
          for (let i = 0; i < count; i++) {
            for (let j = 0; j < count; j++) {
              tctx.drawImage(
                img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh
              )
              ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh)
            }
          }
        } else {
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
        }
        // 进行压缩
        if (!obj.quality) {
          obj.quality = 0.3
        }
        let ndata = canvas.toDataURL('image/jpeg', obj.quality)
        tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0
        callback(ndata)
      }
    }
  }
}
</script>
<style lang="stylus" scoped>
  .upload-wrapper
    width 100%
    background #ffffff
    .upload-box
      position relative
      #upload-ele
        width 100%
        opacity 0
        position absolute
        top 0
        left 0
        width 100%
        height 100%
      .desc
        flexbox()
        align-items center
        justify-content space-between
        padding 20px 10px
        font-size 14px
        box-sizing border-box
        .right
          color #999
    .img-list
      flexbox()
      padding 0 0 15px 10px
      .item
        width 33.3333%
        margin-right 10px
        .img-box
          display inline-block
          vertical-align top
          width 100%
          padding-top 100%
          position relative
          overflow hidden
          position relative
          img
            position absolute
            top 0
            left 0
            width 100%
            height 100%
            object-fit cover
          .icon
            position absolute
            right 0
            top 0
            background red
            color #ffffff
            border-radius 50%
            font-size 18px
            padding 2px
            &:after
              content ''
              position absolute
              left -10px
              bottom -10px
</style>
